//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.goldhuman.IO.Protocol;

import com.goldhuman.Common.Marshal.Marshal;
import com.goldhuman.Common.Marshal.MarshalException;
import com.goldhuman.Common.Marshal.OctetsStream;
import com.goldhuman.Common.TimerObserver;

import java.util.*;

public class Rpc extends com.goldhuman.IO.Protocol.Protocol {
    private static Map<XID, Rpc> map = Collections.synchronizedMap(new HashMap());
    private static HouseKeeper housekeeper = new HouseKeeper();
    private XID xid = new XID();
    private TimerObserver.WatchDog timer = new TimerObserver.WatchDog();
    protected Data argument;
    protected Data result;
    protected long time_policy;

    public Rpc() {
    }

    public int timeElaspe() {
        return (int)this.timer.Elapse();
    }

    public OctetsStream marshal(OctetsStream os) {
        os.marshal(this.xid);
        os.marshal(this.xid.IsRequest() ? this.argument : this.result);
        return os;
    }

    public OctetsStream unmarshal(OctetsStream os) throws MarshalException {
        os.unmarshal(this.xid);
        if (this.xid.IsRequest()) {
            return os.unmarshal(this.argument);
        } else {
            Rpc rpc = (Rpc)map.get(this.xid);
            if (rpc != null) {
                os.unmarshal(rpc.result);
            }

            return os;
        }
    }

    public Object clone() {
        try {
            Rpc rpc = (Rpc)super.clone();
            rpc.xid = (XID)this.xid.clone();
            rpc.timer = new TimerObserver.WatchDog();
            rpc.argument = (Data)this.argument.clone();
            rpc.result = (Data)this.result.clone();
            return rpc;
        } catch (Exception var2) {
            return null;
        }
    }

    public void Process(com.goldhuman.IO.Protocol.Manager manager, com.goldhuman.IO.Protocol.Session session) throws com.goldhuman.IO.Protocol.ProtocolException {
        if (this.xid.IsRequest()) {
            int origin_prior_policy = this.prior_policy;
            this.Server(this.argument, this.result, manager, session);
            if (this.prior_policy == origin_prior_policy) {
                this.xid.ClrRequest();
                manager.Send(session, this);
            } else {
                Task.Dispatch(manager, session, this);
            }

        } else {
            Rpc rpc = (Rpc)map.remove(this.xid);
            if (rpc != null) {
                try {
                    rpc.Client(rpc.argument, rpc.result);
                } catch (ClassCastException var5) {
                    System.out.println(var5.toString());
                }
            }

        }
    }

    protected void Server(Data argument, Data result) throws com.goldhuman.IO.Protocol.ProtocolException {
    }

    protected void Server(Data argument, Data result, Manager manager, Session session) throws com.goldhuman.IO.Protocol.ProtocolException {
        this.Server(argument, result);
    }

    protected void Client(Data argument, Data result) throws ProtocolException {
    }

    protected void OnTimeout() {
    }

    private static Rpc Call(Rpc rpc, Data arg) {
        rpc.xid.SetRequest();
        rpc.argument = arg;
        map.put(rpc.xid, rpc);
        return rpc;
    }

    public static Rpc Call(int type, Data arg) {
        return Call((Rpc) Create(type), arg);
    }

    public static Rpc Call(String type, Data arg) {
        return Call((Rpc) Create(type), arg);
    }

    public static void RemoveRpc(Rpc rpc) {
        map.remove(rpc.xid);
    }

    public long getTimeout() {
        return this.timer.Elapse();
    }

    public abstract static class Data implements Marshal, Cloneable {
        public Data() {
        }

        protected Object clone() {
            try {
                Data data = (Data)super.clone();
                return data;
            } catch (Exception var2) {
                return null;
            }
        }

        public static class DataVector extends Vector implements Marshal, Cloneable {
            protected Data stub;

            private DataVector() {
            }

            public Object clone() {
                try {
                    DataVector v = (DataVector)super.clone();
                    v.stub = (Data)this.stub.clone();
                    return v;
                } catch (Exception var2) {
                    return null;
                }
            }

            public DataVector(Data d) {
                this.stub = d;
            }

            public OctetsStream marshal(OctetsStream os) {
                os.compact_uint32(this.size());

                for(int i = 0; i < this.size(); ++i) {
                    ((Marshal)this.get(i)).marshal(os);
                }

                return os;
            }

            public OctetsStream unmarshal(OctetsStream os) throws MarshalException {
                int size = os.uncompact_uint32();

                for(int i = 0; i < size; ++i) {
                    Data d = (Data)this.stub.clone();
                    d.unmarshal(os);
                    this.add(d);
                }

                return os;
            }
        }
    }

    private static class HouseKeeper implements Observer {
        public HouseKeeper() {
            TimerObserver.GetInstance().addObserver(this);
        }

        public void update(Observable o, Object arg) {
            ArrayList<Rpc> tmp = new ArrayList();
            synchronized(Rpc.map) {
                Iterator<Map.Entry<XID, Rpc>> it = Rpc.map.entrySet().iterator();

                while(true) {
                    if (!it.hasNext()) {
                        break;
                    }

                    Rpc rpc = (Rpc)((Map.Entry)it.next()).getValue();
                    if (rpc.time_policy < rpc.timer.Elapse()) {
                        tmp.add(rpc);
                        it.remove();
                    }
                }
            }

            Iterator<Rpc> it = tmp.iterator();

            while(it.hasNext()) {
                ((Rpc)it.next()).OnTimeout();
            }

        }
    }

    private static class XID implements Marshal, Cloneable {
        public int count;
        private boolean is_request;
        private static int xid_count = 0;
        private static Object xid_locker = new Object();

        private XID() {
            this.count = 0;
            this.is_request = true;
        }

        public OctetsStream marshal(OctetsStream os) {
            return os.marshal(this.is_request ? this.count | Integer.MIN_VALUE : this.count & Integer.MAX_VALUE);
        }

        public OctetsStream unmarshal(OctetsStream os) throws MarshalException {
            this.count = os.unmarshal_int();
            this.is_request = (this.count & Integer.MIN_VALUE) != 0;
            return os;
        }

        public boolean IsRequest() {
            return this.is_request;
        }

        public void ClrRequest() {
            this.is_request = false;
        }

        public void SetRequest() {
            this.is_request = true;
            synchronized(xid_locker) {
                this.count = xid_count++;
            }
        }

        public Object clone() {
            try {
                return super.clone();
            } catch (Exception var2) {
                var2.printStackTrace();
                return null;
            }
        }

        public boolean equals(Object o) {
            return (((XID)o).count & Integer.MAX_VALUE) == (this.count & Integer.MAX_VALUE);
        }

        public int hashCode() {
            return this.count & Integer.MAX_VALUE;
        }
    }
}
